package com.sc.nft.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.sc.nft.annotation.UserLogin;
import com.sc.nft.controller.request.IdRequest;
import com.sc.nft.controller.request.IdStrRequest;
import com.sc.nft.entity.dto.ImGetGroupInfoDTO;
import com.sc.nft.entity.dto.QrCodeAddGroupDTO;
import com.sc.nft.entity.dto.SearchUserInfoAddGroupDTO;
import com.sc.nft.entity.dto.UserCreationGroupDTO;
import com.sc.nft.entity.vo.*;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.helper.ImAccountHelper;
import com.sc.nft.helper.ProhibitedWordsHelper;
import com.sc.nft.pool.UserPool;
import com.sc.nft.service.ImGroupService;
import com.sc.nft.sup.ErrorCode;
import com.sc.nft.sup.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@RequiredArgsConstructor
@RestController
@RequestMapping("/im")
@Api(tags = "即时通讯")
public class ImController {

    private final ImGroupService imGroupService;

    private final RedisTemplate redisTemplate;

    private final RedissonClient redissonClient;

    private final ImAccountHelper imAccountHelper;

    private final ProhibitedWordsHelper prohibitedWordsHelper;

    @ApiOperation(value = "通过daoId,获取腾讯的群组", notes = "通过daoId,获取腾讯的群组", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/getByDaoIdGroup", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result<ImGroupInfoVO> getAppVersion(@Valid @RequestBody IdRequest idRequest) {
        return Result.success(imGroupService.getByDaoIdGroup(idRequest.getId()));
    }

    @ApiOperation(value = "用户加入群组", notes = "用户加入群组", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/userAddGroup", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result userAddGroup(@Valid @RequestBody IdStrRequest idStrRequest) {
        imGroupService.userAddGroup(idStrRequest.getId(), UserPool.getUser());
        return Result.success();
    }

    @ApiOperation(value = "拉用户加入群组", notes = "拉用户加入群组", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/searchUserInfoAddGroup", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result searchUserInfoAddGroup(@Valid @RequestBody SearchUserInfoAddGroupDTO searchUserInfoAddGroupDTO) {
        imGroupService.searchUserInfoAddGroup(searchUserInfoAddGroupDTO);
        return Result.success();
    }

    @ApiOperation(value = "获取秘钥加密签名", notes = "获取秘钥加密签名", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/getToken", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result getToken() {
        Map map = new HashMap();
        map.put("token", ImAccountHelper.getToken(UserPool.getUser().getId()));
        map.put("appId", ImAccountHelper.appId);
//        map.put("key",ImAccountHelper.key);
        map.put("userId", UserPool.getUser().getId());
        return Result.success(map);
    }

//    @ApiOperation(value = "转让群主", notes = "转让群主", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
//    @PostMapping(value = "/transferGroupMaster", produces = MediaType.APPLICATION_JSON_VALUE)
//    @UserLogin
//    public Result transferGroupMaster(@RequestBody TransferGroupMasterDTO transferGroupMasterDTO) {
//        imGroupService.transferGroupMaster(transferGroupMasterDTO);
//        return Result.success();
//    }

    @SneakyThrows
    @ApiOperation(value = "用户创建群组", notes = "用户创建群组", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/userCreationGroup", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result userCreationGroup(@Validated @RequestBody UserCreationGroupDTO userCreationGroupDTO) {
        RLock lock = redissonClient.getLock(StrUtil.format("userCreationGroup:{}", UserPool.getUser().getId()));
        boolean b = lock.tryLock();
        if (!b) {
            throw new GlobalRunTimeException("禁止重复提交");
        }
        try {
            String format = StrUtil.format("userCreationGroupTime:{}", UserPool.getUser().getId());
            Boolean aBoolean = redisTemplate.hasKey(format);
            if (aBoolean) {
                throw new GlobalRunTimeException("30秒内只能创建一个群组");
            }
            boolean b1 = prohibitedWordsHelper.checkContent(userCreationGroupDTO.getGroupName());
            if (!b1) {
                throw new GlobalRunTimeException("群名中蕴含违禁词");
            }
            String s = imGroupService.userCreationGroup(userCreationGroupDTO);
            Map map = new HashMap();
            map.put("groupName", s);
            return Result.success(s);
        } finally {
            lock.unlock();
        }

    }

    @ApiOperation(value = "生成二维码", notes = "生成二维码", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/generateTwoDimensionalCode", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result<GenerateTwoDimensionalCodeVO> generateTwoDimensionalCode(@Validated @RequestBody IdStrRequest idStrRequest) {
        GenerateTwoDimensionalCodeVO generateTwoDimensionalCodeVO = imGroupService.generateTwoDimensionalCode(idStrRequest.getId());
        return Result.success(generateTwoDimensionalCodeVO);
    }

    @ApiOperation(value = "生成二维码H5版本", notes = "生成二维码H5版本", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/generateTwoDimensionalCodeH5", produces = MediaType.APPLICATION_JSON_VALUE)
    public Result<GenerateTwoDimensionalCodeVO> generateTwoDimensionalCodeH5(@Validated @RequestBody IdStrRequest idStrRequest) {
        GenerateTwoDimensionalCodeVO generateTwoDimensionalCodeVO = imGroupService.generateTwoDimensionalCode(idStrRequest.getId());
        return Result.success(generateTwoDimensionalCodeVO);
    }

    @ApiOperation(value = "是否是官方群", notes = "是否是官方群", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/isOfficial", produces = MediaType.APPLICATION_JSON_VALUE)
    public Result<Map> isOfficial(@Validated @RequestBody IdStrRequest idStrRequest) {
        Map map = new HashMap();
        map.put("isOfficial", imGroupService.isOfficial(idStrRequest.getId()));
        return Result.success(map);
    }

    @ApiOperation(value = "扫描二维码判定二维码是否还有效", notes = "扫描二维码判定二维码是否还有效", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/qrCodeValid", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result qrCodeValid(@Validated @RequestBody QrCodeAddGroupDTO qrCodeAddGroupDTO) {
        Boolean qrCode = redisTemplate.hasKey(StrUtil.format("QRCODE:{}-{}", qrCodeAddGroupDTO.getRqCOde(), qrCodeAddGroupDTO.getId()));
        if (!qrCode) {
            throw new GlobalRunTimeException(ErrorCode.QR_CODE);
        }
        // 不能直接使用api接口加入群组,这里是admin的权柄,需要前端自己处理.二维码没过期的情况下给用户注册一下,前端自己申请.
//        imGroupService.userAddGroup(qrCodeAddGroupDTO.getId(),UserPool.getUser());
        // 给用户注册.
        imGroupService.userAddImGroup(UserPool.getUser());
        ImGetGroupInfoDTO imGetGroupInfoDTO = new ImGetGroupInfoDTO();
        imGetGroupInfoDTO.setGroupIdList(Arrays.asList(qrCodeAddGroupDTO.getId()));
        ImGroupInfoAllResultVO imGroupInfoVO = (ImGroupInfoAllResultVO) imAccountHelper.getGroupInfo(imGetGroupInfoDTO, ImGroupInfoAllResultVO.class);
        List<ImGroupInfoAllResultVO.GroupInfoDTO> collect = imGroupInfoVO.getGroupInfo().stream().filter(groupInfoDTO -> groupInfoDTO.getErrorCode().equals(0)).collect(Collectors.toList());
        if (CollUtil.isEmpty(collect)) {
            throw new GlobalRunTimeException("群不存在或已解散");
        }
        ImGroupInfoAllResultVO.GroupInfoDTO groupInfoDTO = collect.get(0);
        Map map = new HashMap();
        map.put("pattern", groupInfoDTO.getApplyJoinOption().equals("FreeAccess") ? Boolean.FALSE : Boolean.TRUE);
        return Result.success(map);
    }

    @ApiOperation(value = "用户是否在群组内", notes = "用户是否在群组内", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/userIsExistGroup", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result<UserIsExistGroupVO> userIsExistGroup(@Validated @RequestBody IdStrRequest idStrRequest) {
        return Result.success(imGroupService.userIsExistGroup(idStrRequest.getId()));
    }

    @ApiOperation(value = "解散群", notes = "解散群", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/destroyGroup", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result adminDestroyGroup(@Validated @RequestBody IdStrRequest groupId) {
        imGroupService.adminDestroyGroup(groupId.getId());
        return Result.success();
    }


    @ApiOperation(value = "群基本信息", notes = "群基本信息", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/groupIsBanned", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result<GroupIsBannedVO> groupIsBanned(@Validated @RequestBody IdStrRequest groupId) {
        GroupIsBannedVO groupIsBannedVO=new GroupIsBannedVO();
        ImGroupInfoAllResultVO.GroupInfoDTO groupInfoDTO = imGroupService.groupIsBanned(groupId.getId());
        groupIsBannedVO.setGroupIsBanned(groupInfoDTO.getMuteAllMember().equals("Off") ? Boolean.FALSE : Boolean.TRUE);
        groupIsBannedVO.setApplyJoinOption(groupInfoDTO.getApplyJoinOption());
        return Result.success(groupIsBannedVO);
    }

}
